View Javadoc

1   /***
2    * Redistribution and use of this software and associated documentation
3    * ("Software"), with or without modification, are permitted provided
4    * that the following conditions are met:
5    *
6    * 1. Redistributions of source code must retain copyright
7    *    statements and notices.  Redistributions must also contain a
8    *    copy of this document.
9    *
10   * 2. Redistributions in binary form must reproduce the
11   *    above copyright notice, this list of conditions and the
12   *    following disclaimer in the documentation and/or other
13   *    materials provided with the distribution.
14   *
15   * 3. The name "Exolab" must not be used to endorse or promote
16   *    products derived from this Software without prior written
17   *    permission of Exoffice Technologies.  For written permission,
18   *    please contact info@exolab.org.
19   *
20   * 4. Products derived from this Software may not be called "Exolab"
21   *    nor may "Exolab" appear in their names without prior written
22   *    permission of Exoffice Technologies. Exolab is a registered
23   *    trademark of Exoffice Technologies.
24   *
25   * 5. Due credit should be given to the Exolab Project
26   *    (http://www.exolab.org/).
27   *
28   * THIS SOFTWARE IS PROVIDED BY EXOFFICE TECHNOLOGIES AND CONTRIBUTORS
29   * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
30   * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
31   * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
32   * EXOFFICE TECHNOLOGIES OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33   * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
35   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
37   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
39   * OF THE POSSIBILITY OF SUCH DAMAGE.
40   *
41   * Copyright 2005 (C) Exoffice Technologies Inc. All Rights Reserved.
42   *
43   * $Id: AbstractConsumerMessageHandle.java,v 1.2 2005/08/30 07:26:49 tanderson Exp $
44   */
45  package org.exolab.jms.messagemgr;
46  
47  import java.sql.Connection;
48  import javax.jms.JMSException;
49  import javax.jms.MessageConsumer;
50  
51  import org.apache.commons.logging.Log;
52  import org.apache.commons.logging.LogFactory;
53  
54  import org.exolab.jms.client.JmsDestination;
55  import org.exolab.jms.message.MessageImpl;
56  import org.exolab.jms.persistence.DatabaseService;
57  import org.exolab.jms.persistence.PersistenceException;
58  
59  
60  /***
61   * A {@link MessageHandle} for a consumer.
62   *
63   * @author <a href="mailto:tma@netspace.net.au">Tim Anderson</a>
64   * @version $Revision: 1.2 $ $Date: 2005/08/30 07:26:49 $
65   */
66  abstract class AbstractConsumerMessageHandle implements MessageHandle {
67  
68      /***
69       * The underlying handle.
70       */
71      private final MessageHandle _handle;
72  
73      /***
74       * The consumer's identity.
75       */
76      private long _consumerId;
77  
78      /***
79       * The consumer's persistent identity.
80       */
81      private final String _persistentId;
82  
83      /***
84       * Detetmines if this handle is persistent.
85       */
86      private boolean _persistent;
87  
88      /***
89       * The logger.
90       */
91      private static final Log _log
92              = LogFactory.getLog(AbstractConsumerMessageHandle.class);
93  
94  
95      /***
96       * Construct a new <code>AbstractConsumerMessageHandle</code>.
97       *
98       * @param handle   the underlying handle
99       * @param consumer the consumer of the handle
100      * @throws JMSException if the underlying message can't be referenced
101      */
102     public AbstractConsumerMessageHandle(MessageHandle handle,
103                                          ConsumerEndpoint consumer)
104             throws JMSException {
105         this(handle, consumer.getId(), consumer.getPersistentId());
106     }
107 
108     /***
109      * Construct a new <code>AbstractConsumerMessageHandle</code>.
110      *
111      * @param handle       the underlying handle
112      * @param persistentId the persistent identity of the consumer. May be
113      *                     <code>null</code>
114      * @throws JMSException if the underlying message can't be referenced
115      */
116     public AbstractConsumerMessageHandle(MessageHandle handle,
117                                          String persistentId)
118             throws JMSException {
119         this(handle, -1L, persistentId);
120     }
121 
122     /***
123      * Construct a new <code>AbstractConsumerMessageHandle</code>.
124      *
125      * @param handle       the underlying handle
126      * @param consumerId   the consumer identifier
127      * @param persistentId the persistent identity of the consumer. May be
128      *                     <code>null</code>
129      * @throws JMSException if the underlying message can't be referenced
130      */
131     protected AbstractConsumerMessageHandle(MessageHandle handle, long consumerId,
132                                             String persistentId)
133             throws JMSException {
134         if (handle == null) {
135             throw new IllegalArgumentException("Argument 'handle' is null");
136         }
137         _handle = handle;
138         _consumerId = consumerId;
139         _persistentId = persistentId;
140         _handle.getMessageRef().reference();
141     }
142 
143     /***
144      * Returns the message identifier.
145      *
146      * @return the message identifier
147      */
148     public String getMessageId() {
149         return _handle.getMessageId();
150     }
151 
152     /***
153      * Indicates if a message has been delivered to a {@link MessageConsumer},
154      * but not acknowledged.
155      *
156      * @param delivered if <code>true</code> indicates that an attempt has been
157      *                  made to deliver the message
158      */
159     public void setDelivered(boolean delivered) {
160         _handle.setDelivered(delivered);
161     }
162 
163     /***
164      * Returns if an attempt has already been made to deliver the message.
165      *
166      * @return <code>true</code> if delivery has been attempted
167      */
168     public boolean getDelivered() {
169         return _handle.getDelivered();
170     }
171 
172     /***
173      * Returns the priority of the message.
174      *
175      * @return the message priority
176      */
177     public int getPriority() {
178         return _handle.getPriority();
179     }
180 
181     /***
182      * Returns the time that the corresponding message was accepted, in
183      * milliseconds.
184      *
185      * @return the time that the corresponding message was accepted
186      */
187     public long getAcceptedTime() {
188         return _handle.getAcceptedTime();
189     }
190 
191     /***
192      * Returns the time that the message expires.
193      *
194      * @return the expiry time
195      */
196     public long getExpiryTime() {
197         return _handle.getExpiryTime();
198     }
199 
200     /***
201      * Determines if the message has expired.
202      *
203      * @return <code>true</code> if the message has expired, otherwise
204      *         <code>false</code>
205      */
206     public boolean hasExpired() {
207         return _handle.hasExpired();
208     }
209 
210     /***
211      * Returns the handle's sequence number.
212      *
213      * @return the sequence number
214      */
215     public long getSequenceNumber() {
216         return _handle.getSequenceNumber();
217     }
218 
219     /***
220      * Returns the message destination.
221      *
222      * @return the message destination
223      */
224     public JmsDestination getDestination() {
225         return _handle.getDestination();
226     }
227 
228     /***
229      * Returns the consumer identity associated with the message.
230      *
231      * @return the consumer identity associated with the message, or *
232      *         <code>-1</code> if the message isn't associated with a consumer
233      */
234     public long getConsumerId() {
235         return _consumerId;
236     }
237 
238     /***
239      * Returns the name of the consumer endpoint that owns this handle. If it is
240      * set, then a consumer owns it exclusively, otherwise the handle may be
241      * shared across a number of consumers
242      *
243      * @return the consumer name, or <code>null</code>
244      */
245     public String getConsumerPersistentId() {
246         return _persistentId;
247     }
248 
249     /***
250      * Returns the connection identity associated with the message.
251      *
252      * @return the connection identity associated with the message, or
253      *         <code>-1</code> if the message isn't associated with a
254      *         connection
255      */
256     public long getConnectionId() {
257         return _handle.getConnectionId();
258     }
259 
260     /***
261      * Determines if the handle is persistent.
262      *
263      * @return <code>true</code> if the handle is persistent; otherwise
264      *         <code>false</code>
265      */
266     public boolean isPersistent() {
267         return _persistent;
268     }
269 
270     /***
271      * Returns the message associated with this handle.
272      *
273      * @return the associated message, or <code>null</code> if the handle is no
274      *         longer valid
275      * @throws JMSException for any error
276      */
277     public MessageImpl getMessage() throws JMSException {
278         return _handle.getMessage();
279     }
280 
281     /***
282      * Makes the handle persistent.
283      *
284      * @throws JMSException for any persistence error
285      */
286     public void add() throws JMSException {
287         try {
288             DatabaseService service = DatabaseService.getInstance();
289             Connection connection = service.getConnection();
290             service.getAdapter().addMessageHandle(connection, this);
291         } catch (PersistenceException exception) {
292             final String msg = "Failed to make handle persistent";
293             _log.error(msg, exception);
294             throw new JMSException(msg + ": " + exception.getMessage());
295         }
296         _persistent = true;
297     }
298 
299     /***
300      * Update the persistent handle.
301      *
302      * @throws JMSException for any persistence error
303      */
304     public void update() throws JMSException {
305         try {
306             DatabaseService service = DatabaseService.getInstance();
307             Connection connection = service.getConnection();
308             service.getAdapter().updateMessageHandle(connection, this);
309         } catch (PersistenceException exception) {
310             final String msg = "Failed to update persistent handle";
311             _log.error(msg, exception);
312             throw new JMSException(msg + ": " + exception.getMessage());
313         }
314     }
315 
316     /***
317      * Destroy this handle. If this is the last handle to reference the message,
318      * also destroys the message
319      *
320      * @throws JMSException for any error
321      */
322     public void destroy() throws JMSException {
323         if (_persistent) {
324             try {
325                 DatabaseService service = DatabaseService.getInstance();
326                 Connection connection = service.getConnection();
327                 service.getAdapter().removeMessageHandle(connection, this);
328             } catch (PersistenceException exception) {
329                 final String msg = "Failed to destroy persistent handle";
330                 _log.error(msg, exception);
331                 throw new JMSException(msg + ": " + exception.getMessage());
332             }
333         }
334         _handle.destroy();
335         _persistent = false;
336     }
337 
338     /***
339      * Release the message handle back to the cache, to recover an unsent or
340      * unacknowledged message.
341      *
342      * @throws JMSException for any error
343      */
344     public void release() throws JMSException {
345         if (_handle instanceof AbstractMessageHandle) {
346             ((AbstractMessageHandle) _handle).release(this);
347         } else {
348             _handle.release();
349         }
350     }
351 
352     /***
353      * Returns the message reference.
354      *
355      * @return the message reference, or <code>null</code> if none has been set
356      */
357     public MessageRef getMessageRef() {
358         return _handle.getMessageRef();
359     }
360 
361     /***
362      * Set the consumer identifier.
363      *
364      * @param consumerId the consumer identifier
365      */
366     protected void setConsumerId(long consumerId) {
367         _consumerId = consumerId;
368     }
369 
370     /***
371      * Indicates if the handle is persistent.
372      *
373      * @param persistent if <code>true</code> indicates the handle is
374      *                   persistent
375      */
376     protected void setPersistent(boolean persistent) {
377         _persistent = persistent;
378     }
379 
380 }
381